﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Reflection;
using Pixysoft.Weblications.Sango.Protocol.player;
using Pixysoft.Weblications.Sango.Protocol.equipment;
using Pixysoft.Weblications.Sango.Dao;
using Pixysoft.Weblications.Sango.Protocol;
using Pixysoft.Weblications.Sango.Formular;
using Pixysoft.Weblications.Sango.Constant;
using Pixysoft.Weblications.Sango.Environment;
using Pixysoft.Weblications.Sango.Battle;
using Pixysoft.Weblications.Sango.Constant.battle;
using Pixysoft.Tools;
using Pixysoft.Framework.Verifications;
using Pixysoft.Weblications.Sango.Protocol.stage;
using Pixysoft.Weblications.Sango.Command.stage;

namespace Pixysoft.Weblications.Sango.Command.stage_pve
{
    partial class SangoStagePveHandler
    {
        public stagepve_fight stagepve_fight(double geox, double geoy, long stageserialcode)
        {
            string userCode = SangoManager.Authentication();

            stagepve_fight response = ReflectionManager.CreatePojo<stagepve_fight>();
            response.Succeed = false;

            Entities.Usr_Profile profile = UsrProfileDao.getUsrProfile(userCode);
            Entities.Usr_Activity activity = UsrActivityDao.getHistory(userCode);

            Entities.War_Stage warStage = WarStageHelper.searchStageByCode(stageserialcode);

            Entities.Usr_Queue queue = UsrQueueDao.UsrQueueStartup(userCode, CtiQueueTypecodeCollection.BATTLE, userCode, BattleFormular.getBattleCooldownTimespan(activity));

            bool needCooldown = StageFormular.needCooldownQueue(warStage);

            if (queue == null && needCooldown)
            {
                response.Message = "队列冷却中";
                return response;
            }

            if (!StageDao.stageCanAttack(userCode, warStage))
            {
                response.Message = "当前关卡无法攻击，前置未完成";
                return response;
            }

            if (activity.Freebattlecount <= 0 && !StageFormular.isFreeAttackNpc(activity.Freebattletypecode))
            {
                response.Message = "无行动力";
                return response;
            }

            bool hasAttackStage = StageDao.tryGetStageBySerialcode(profile.Usercode, warStage.Stageserialcode) != null;

            Entities.Usr_Section section = UsrSectionDao.GetSection(userCode);

            Entities.Usr_Mission mission = MissionDao.getMission(userCode);

            PvxBattleHistory pvxHistory = null;

            IEntityNoebeTransaction command = SettingHelper.EntityTransaction;

            command.Begin(delegate()
            {
                if (hasAttackStage)
                {
                    // 不允许攻打武将关卡
                    if (warStage.Stagetypecode == WarStageTypecodeCollection.OFFICER)
                    {
                        response.Message = "无法重复攻击";
                        return;
                    }

                    Entities.War_Stagehistory warHistory = WarStagehistoryHelper.searchHistory(section.Sectionserialcode, warStage.Stageserialcode);

                    if (warStage.Stageplaytimes != PlayerFormular.default_number_empty && warHistory.Attackcount >= warStage.Stageplaytimes)
                    {
                        response.Message = "关卡已无攻打次数";
                        return;
                    }

                    // 消耗全局刷怪数目刷图

                    pvxHistory = repeatAttack(response, command, section, profile, warStage, warHistory);
                }
                else
                {			// 初次过图

                    pvxHistory = firstAttack(response, command, section, profile, warStage);
                }


                // 判断是否级别不够
                if (StageFormular.needDecreaseActionPoint(profile, pvxHistory.BattleResult == BattleResultCollection.ATTACKWIN))
                {
                    // 判断是否免费攻打

                    if (StageFormular.isFreeAttackNpc(activity.Freebattletypecode))
                    {
                        activity.Freebattletypecode = (activity.Freebattletypecode - FreeBattleTypecodeCollection.ATTACK_PVE);
                    }
                    else
                    {
                        activity.Usedbattlecount = activity.Usedbattlecount + 1;
                        activity.Freebattlecount = activity.Freebattlecount - 1;
                    }
                }


                // 增加军魂

                if (StageFormular.needDecreaseActionPoint(profile, pvxHistory.BattleResult == BattleResultCollection.ATTACKWIN))
                {
                    UsrProfileDao.increaseSoulvalue(profile, StageFormular.GetPveSoulValue(warStage, profile, true));
                    command.Update(profile);
                }


                command.Update(activity);

                if (needCooldown)
                {
                    // do nothing
                }
                else
                {
                    UsrQueueDao.UsrQueueRestart(queue, StageFormular.default_stage_cooling);
                }

                command.Update(queue);

                Entities.Log_Pvxbattlevideo video = LogPvxBattleVideoDao.createLog(section.Sectionserialcode, warStage.Stageserialcode, pvxHistory);
                command.Insert(video);
                response.videocode = video.Logcode;

                if (MissionDao.processDailyMission(mission, MissionDailyCollection.ATTACK_PVE))
                {
                    command.Update(mission);
                }

                command.Commit();


                if (!hasAttackStage)
                {
                    stage_list stagelist = new SangoStageHandler().stage_list(geox, geoy);
                    response.stages = stagelist.stages;
                    response.map = stagelist.map;
                }

                response.profile = UsrProfileFacade.ToProfile(profile);
                response.activity = UsrProfileFacade.ToActivity(profile, activity);
                response.queue = UsrQueueFacade.ToQueue(queue);

                response.Succeed = true;
            });

            return response;
        }

        private PvxBattleHistory repeatAttack(stagepve_fight response, IEntityNoebeTransaction command,
            Entities.Usr_Section section, Entities.Usr_Profile profile, Entities.War_Stage stage, Entities.War_Stagehistory warHistory)
        {
            Entities.Usr_Tactical tactical = TacticalDao.getUsrDefaultTactical(profile.Usercode);

            PvxBattleHistory history = getAttackResult(profile, tactical, stage);

            if (stage.Stageplaytimes != PlayerFormular.default_number_empty)// 如果攻打次数大于0，才计算
            {
                if (history.BattleResult != BattleResultCollection.ATTACKWIN)
                {
                    return history;
                }

                if (!WarStagehistoryHelper.increateAttackHistory(section.Sectionserialcode, stage.Stageserialcode, stage.Stageplaytimes))
                {
                    throw Exceptions.UnexpectedResultException("no times left.");
                }
            }

            // 添加装备

            bool dropEqm = StageFormular.isDropEquipment(stage);

            Entities.Usr_Equipment eqm = null;

            if (dropEqm)
            {
                eqm = EquipmentDao.tryDropUserEquipment(command, profile, stage.Equipmentserialcode);

                if (eqm != null)
                {
                    response.eqm = EquipmentFacade.ToEquipment(eqm, new List<Entities.Usr_Equipmentextra>());
                }
            }

            return history;
        }

        private PvxBattleHistory firstAttack(stagepve_fight response, IEntityNoebeTransaction command,
            Entities.Usr_Section section, Entities.Usr_Profile profile, Entities.War_Stage stage)
        {
            // 战斗

            Entities.Usr_Tactical tactical = TacticalDao.getUsrDefaultTactical(profile.Usercode);

            PvxBattleHistory history = getAttackResult(profile, tactical, stage);

            // 判断战斗结果

            if (history.BattleResult != BattleResultCollection.ATTACKWIN)
            {
                return history;
            }

            // 添加装备

            bool dropEqm = StageFormular.isDropEquipment(stage);

            Entities.Usr_Equipment eqm = null;

            if (dropEqm)
            {
                eqm = EquipmentDao.tryDropUserEquipment(command, profile, stage.Equipmentserialcode);

                if (eqm != null)
                {
                    response.eqm = EquipmentFacade.ToEquipment(eqm, new List<Entities.Usr_Equipmentextra>());
                }
            }

            // 添加武将

            if (stage.Officerserialcode != PlayerFormular.default_number_empty)
            {
                Entities.Sys_Officer officer = SysOfficerHelper.searchBySerialcode(stage.Officerserialcode);

                Entities.Usr_Officer uofficer = OfficerDao.createUserOfficer(profile.Usercode, profile.Nickname, officer);

                command.Insert(uofficer);
            }

            // 添加关卡

            Entities.Usr_Map map = StageDao.getMapBySerialcode(profile.Usercode, stage.Mapserialcode);

            command.Insert(StageDao.createStage(section, profile, map, stage));

            // 判断是否通关          

            if (stage.Locationtypecode == WarStageLocationTypecodeCollection.FINISH)
            {
                map.Mapstatus = WarMapStatusCollection.FINISH;
                map.Finishdate = (GlobalTimer.Instance.ToTimeSequence());
            }

            else if (stage.Locationtypecode == WarStageLocationTypecodeCollection.PASS)
            {
                map.Mapstatus = (WarMapStatusCollection.PASS);
                map.Passdate = (GlobalTimer.Instance.ToTimeSequence());

                // 开新图

                foreach (Entities.War_Map nextwarmap in WarStageHelper.getChildMapsBySerialcode(map.Mapserialcode))
                {
                    Entities.Usr_Map nextUserMap = StageDao.createMap(profile, nextwarmap);

                    if (StageDao.tryGetMapBySerialcode(profile.Usercode, nextUserMap.Mapserialcode) == null)
                    {
                        command.Insert(nextUserMap);
                    }
                }
            }
            command.Update(map);

            return history;
        }

        private static PvxBattleHistory getAttackResult(Entities.Usr_Profile profile, Entities.Usr_Tactical tactical, Entities.War_Stage stage)
        {
            PvxBattle battle = BattleFactory.createBattle();

            BattleTeam attacks = BattleFactory.createBattleTeam(profile, tactical);
            BattleTeam defenses = BattleFactory.createBattleTeam(stage);

            battle.setAttackes(attacks);
            battle.setDefenses(defenses);

            if (!attacks.verify())
            {
                return battle.createBattleHistory(BattleFormular.default_scenetype, BattleFormular.default_stufftype, BattleResultCollection.DEFENSEWIN);
            }
            if (!defenses.verify())
            {
                return battle.createBattleHistory(BattleFormular.default_scenetype, BattleFormular.default_stufftype, BattleResultCollection.ATTACKWIN);
            }

            PvxBattleHistory history = battle.run(BattleFormular.default_scenetype, BattleFormular.default_stufftype);
            return history;
        }

    }

    public interface stagepve_fight : ISangoResponse
    {
        string videocode { get;set;}

        player_queue queue { get;set;}
        player_profile profile { get;set;}
        player_activity activity { get;set;}

        usr_equipment eqm { get;set;}

        List<stage_stage> stages { get;set;}
        stage_map map { get;set;}
    }
}
